package controller

import (
	"log"
	"strings"
	"user-go/entity"

	"github.com/androidsr/sc-go/sbuilder"
	"github.com/androidsr/sc-go/sgin"

	"github.com/androidsr/sc-go/model"
	"github.com/androidsr/sc-go/sno"
	"github.com/androidsr/sc-go/sorm"
	"github.com/gin-gonic/gin"
)

func init() {
	sgin.AddRouter(SysMenusController{})
}

type SysMenusController struct {
}

// 查询
// @Router [get] [/sysmenus/:id]
func (SysMenusController) Get(c *gin.Context) any {
	id := c.Param("id")
	data := new(entity.SysMenus)
	data.Id = id
	err := sorm.DB.SelectOne(data, data)
	if err != nil {
		return model.NewFailDefault("获取对象失败")
	}
	return data
}

// 增加
// @Router [post] [/sysmenus]
func (SysMenusController) Post(c *gin.Context, in *entity.SysMenus) any {
	in.Id = sno.GetString()
	sorm.DB.Insert(in)
	return model.NewOK(nil)
}

// 修改
// @Router [put] [/sysmenus/edit]
func (SysMenusController) Put(c *gin.Context, in *entity.SysMenus) any {
	sorm.DB.UpdateById(in)
	return model.NewOK(nil)
}

// 删除
// @Router [delete] [/sysmenus/:id]
func (SysMenusController) Delete(c *gin.Context) any {
	id := c.Param("id")
	if id == "" {
		return model.NewFailDefault("主键不能为空")
	}
	sorm.DB.Delete(entity.SysMenus{Id: id})
	return model.NewOK(nil)
}

type SysMenusQuery struct {
	Page      model.PageInfo  `json:"page"`
	QueryData entity.SysMenus `json:"queryData"`
}

// 查询列表
// @Router [post] [/sysmenus/page]
func (SysMenusController) QueryTables(c *gin.Context, in *SysMenusQuery) any {
	sql := `select * from sys_menus a where 1=1 `
	data := make([]entity.SysMenus, 0)
	b := sbuilder.StructToBuilder(in.QueryData, sql)
	sql, values := b.Build()
	return sorm.DB.SelectPage(&data, in.Page, sql, values...)
}

// 分页下拉
// @Router [post] [/sysmenus/list]
func (SysMenusController) QuerySelect(c *gin.Context, in *model.SelectQueryDTO) any {
	sql := `select a.id as value, a.title as label from sys_menus a where 1=1 `
	data := make([]model.SelectVO, 0)
	b := sbuilder.Builder(sql)
	b.Like("CONCAT(id,title)", in.Label)
	b.Multiple().Ors(b.In("id", in.Selected))
	sql, values := b.Build()
	return sorm.DB.SelectPage(&data, in.Page, sql, values...)
}

// @Router [post] [/sysmenus/menuselect]
func (SysMenusController) MenuSelect(c *gin.Context, in *model.SelectQueryDTO) any {
	bean := new(entity.SysMenus)
	bean.Id = in.Of
	err := sorm.DB.GetOne(bean)
	if err != nil {
		return model.NewFailDefault("获取菜单信息时失败")
	}
	sql := `select a.id as value, a.title as label from sys_buttons a where id is not null`
	data := make([]model.SelectVO, 0)
	b := sbuilder.Builder(sql)
	b.Like("CONCAT(id,title)", in.Label)
	b.Multiple().Ors(b.In("id", strings.Split(bean.BtnId, ",")))
	sql, values := b.Build()
	return sorm.DB.SelectPage(&data, in.Page, sql, values...)
}

type Menus struct {
	Id        string              `json:"id"`
	Title     string              `json:"title"`
	Url       string              `json:"key"`
	Icon      string              `json:"icon"`
	SuperId   string              `json:"superId"`
	BtnId     string              `json:"btnId"`
	MenuOrder string              `json:"menuOrder"`
	Children  []Menus             `json:"children"`
	Buttons   []entity.SysButtons `json:"buttons"`
}

// @Router [post] [/sysmenus/home]
func (SysMenusController) Home(c *gin.Context) any {
	role := c.GetString(ROLE)
	ids := strings.Split(role, ",")
	if len(ids) < 1 {
		return model.NewFailDefault("用户无权限")
	}
	data := make([]entity.SysMenus, 0)
	sql := `select DISTINCT a.* from sys_menus a left join sys_role_menu b on a.id = b.menu_id left join sys_roles c on b.role_id = c.id where 1=1 `
	b := sbuilder.Builder(sql)
	b.In("c.id", ids)
	b.Append("order by a.menu_order asc")
	sql, values := b.Build()
	err := sorm.DB.Select(&data, sql, values...)
	if err != nil {
		log.Println(err)
		return model.NewFailDefault("查询数据失败")
	}
	list := make([]Menus, 0)
	for _, m := range data {
		if m.SuperId != "" {
			continue
		}
		item := Menus{}
		item.Title = m.Title
		item.Id = m.Id
		item.Icon = m.Icon
		if m.Url == "" {
			item.Url = m.Id
		} else {
			item.Url = m.Url
		}
		item.Children = readChild(data, m, ids)
		list = append(list, item)
	}
	return list
}

// @Router [post] [/sysmenus/roles]
func (SysMenusController) Roles(c *gin.Context) any {
	userId := c.GetString(USER)
	var ids []string
	if userId != "admin" {
		role := c.GetString(ROLE)
		ids = strings.Split(role, ",")
		if len(ids) < 1 {
			return model.NewFailDefault("用户无权限")
		}
	}

	data := make([]entity.SysMenus, 0)
	sql := `select DISTINCT a.* from sys_menus a left join sys_role_menu b on a.id = b.menu_id left join sys_roles c on b.role_id = c.id where 1=1 `
	b := sbuilder.Builder(sql)
	b.In("c.id", ids)
	b.Append("order by a.menu_order asc")
	sql, values := b.Build()
	err := sorm.DB.Select(&data, sql, values...)
	if err != nil {
		return model.NewFailDefault("查询数据失败")
	}
	list := make([]Menus, 0)
	for _, m := range data {
		if m.SuperId != "" {
			continue
		}
		item := Menus{}
		item.Title = m.Title
		item.Id = m.Id
		item.Icon = m.Icon
		item.Url = m.Url
		item.Children = readChild(data, m, nil)
		list = append(list, item)
	}
	return list
}

func readChild(
	data []entity.SysMenus, suMenu entity.SysMenus, roleIds []string) []Menus {
	result := make([]Menus, 0)
	for _, cur := range data {
		strId := suMenu.Id
		if cur.SuperId == strId {
			item := Menus{}
			item.Title = cur.Title
			if cur.Url == "" {
				item.Url = cur.Id
			} else {
				item.Url = cur.Url
			}
			item.Icon = cur.Icon
			item.Id = cur.Id
			if cur.BtnId != "" && len(roleIds) > 0 {
				buttons := make([]entity.SysButtons, 0)
				for _, v := range roleIds {
					bean := new(entity.SysRoleMenu)
					bean.RoleId = v
					bean.MenuId = cur.Id
					err := sorm.DB.GetOne(bean)
					if err != nil {
						log.Println(err)
						return nil
					}

					btnInfo := make([]entity.SysButtons, 0)
					ids := strings.Split(bean.ButtonIds, ",")

					mk := make([]interface{}, 0)
					for _, v := range ids {
						mk = append(mk, v)
					}
					b := sbuilder.Builder("select * from sys_buttons")
					b.In("id", ids)
					b.Append("order by order_id")
					sql, values := b.Build()
					err = sorm.DB.Select(&btnInfo, sql, values...)
					if err != nil {
						log.Println(err)
						return nil
					}
					buttons = append(buttons, btnInfo...)
				}
				item.Buttons = buttons
			}
			item.Children = readChild(data, cur, roleIds)
			result = append(result, item)
		}
	}
	return result
}
